# -*- coding: utf-8 -*-
# @File:     order_queue.py
# @Author:
# @DateTime: 2025/06/18/13:47
import json
import time
import traceback

from aioredis import from_url

from app.conf import settings
from app.utils.logger import logger

acquire_timeout = 45
lock_key = 'order_lock_key'
cnn = from_url(
        url=settings.REDIS_URL, port=settings.REDIS_PORT, password=settings.REDIS_PASSWORD, db=settings.REDIS_DB, encoding="utf-8", decode_responses=True
    )


async def key_add_order_queue(queue_name, item):

    end = time.time() + acquire_timeout
    while time.time() < end:
        if not await cnn.get(lock_key):
            await cnn.set(lock_key, lock_key, acquire_timeout)
            try:
                await cnn.rpush(queue_name, item)
                return True
            except:
                logger.error("添加排序队列失败")
                return False
            finally:
                await cnn.delete(lock_key)
        time.sleep(0.5)
    return False


async def key_remove_order_queue(queue_name, item):
    cnn = from_url(
        url=settings.REDIS_URL, port=settings.REDIS_PORT, password=settings.REDIS_PASSWORD, db=settings.REDIS_DB, encoding="utf-8", decode_responses=True
    )
    try:
        end = time.time() + acquire_timeout
        while time.time() < end:
            try:
                lock = await cnn.get(lock_key)
            except:
                print(traceback.format_exc())
                lock = None
            if not lock:
                await cnn.set(lock_key, lock_key, acquire_timeout)
                try:
                    await cnn.lrem(queue_name, 0, item)
                    return True
                except:
                    logger.error("删除排序队列失败")
                    return False
                finally:
                    await cnn.delete(lock_key)
            time.sleep(0.5)
        return False
    finally:
        await cnn.close()


async def get_order_queue_length(queue_name):
    end = time.time() + acquire_timeout
    while time.time() < end:
        if not await cnn.get(lock_key):
            await cnn.set(lock_key, lock_key, acquire_timeout)
            try:
                return await cnn.llen(queue_name)
            except:
                logger.error("添加排序队列失败")
                return -1
            finally:
                await cnn.delete(lock_key)
        time.sleep(0.5)
    return -1


async def get_order_queue_item_index(queue_name, item):
    end = time.time() + acquire_timeout
    while time.time() < end:
        if not await cnn.get(lock_key):
            await cnn.set(lock_key, lock_key, acquire_timeout)
            try:
                queue_list = await cnn.lrange(queue_name, 0, -1)
                val = str(item).encode("utf-8")
                if val in queue_list:
                    index = queue_list.index(val)
                    index = index + 1
                else:
                    index = None
                return index
            except:
                logger.error("添加排序队列失败")
                return None
            finally:
                await cnn.delete(lock_key)
        time.sleep(0.5)
    return None


async def clear_order_queue(queue_name):
    end = time.time() + acquire_timeout
    while time.time() < end:
        if not await cnn.get(lock_key):
            await cnn.set(lock_key, lock_key, acquire_timeout)
            try:
                await cnn.ltrim(queue_name, 1, 0)
                return True
            except:
                logger.error("添加排序队列失败")
                return False
            finally:
                await cnn.delete(lock_key)
        time.sleep(0.5)
    return False


async def update_task_state(task_id, state, result):
    cnn = from_url(
        url=settings.REDIS_URL, port=settings.REDIS_PORT, password=settings.REDIS_PASSWORD, db=settings.REDIS_DB, encoding="utf-8", decode_responses=True
    )
    try:
       task_data = await cnn.get(f'task_{task_id}')
       if task_data:
           data = json.loads(task_data)
           data['state'] = state
           data['result_list'] = result
       else:
           data = {'id': task_id, 'state': state, 'result_list': result}

       await cnn.set(f'task_{task_id}', json.dumps(data), 300)
    finally:
        await cnn.close()





